/**
 * @file TaskQueue.cc
 * @brief 任务队列类的实现
 */

#include "TaskQueue.hpp"
#include "MutexLock.hpp"
#include <iostream>

using std::cout;
using std::endl;

namespace wd
{

// 构造函数：初始化任务队列
TaskQueue::TaskQueue(size_t sz)
: _queSize(sz)
, _mutex()
, _notFull(_mutex)
, _notEmpty(_mutex)
, _flag(true)
{
    cout << "TaskQueue(size_t)" << endl;
}

// 检查队列是否已满
bool TaskQueue::full() const
{
    return _que.size() == _queSize;
}

// 检查队列是否为空
bool TaskQueue::empty() const
{
    return _que.size() == 0;
}

// 生产者：向队列添加任务
void TaskQueue::push(ElemType ele)
{
    MutexLockGuard autolock(_mutex);
    while(full()) {// 使用while是为了防止虚假唤醒
        _notFull.wait();
    }

    _que.push(ele);
    //通知消费者线程取数据
    _notEmpty.notify();
}

// 消费者：从队列取出任务
ElemType TaskQueue::pop()
{
    //利用RAII的特性
    MutexLockGuard autolock(_mutex);
    while(_flag && empty()) {
        _notEmpty.wait();
    }

    if(_flag) {
        ElemType tmp = _que.front();
        _que.pop();

        //通知生产者线程放数据
        _notFull.notify();
        return tmp;
    } else {
        return nullptr;
    }
}

// 唤醒所有等待的线程
void TaskQueue::wakeup()
{
    _flag = false;
    _notEmpty.notifyAll();
}
}//end of namespace wd
